package com.example.controller;

import cn.hutool.core.map.MapUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.api.R;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.common.lang.Result;
import com.example.entity.*;
import com.example.service.CommentService;
import com.example.service.PostService;
import com.example.vo.PostVo;
import com.fasterxml.jackson.core.JsonProcessingException;
import org.apache.shiro.authz.annotation.RequiresAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Controller;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;
import org.springframework.util.StringUtils;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;
import java.util.*;

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author JackLin
 * @since 2019-07-30
 */
@Controller
public class PostController extends BaseController {

    /**
     * 分类展示，保存currentCategoryId是为了回显当前选择的栏目
     *
     * @param id 正则{id:\\d*}:匹配冒号后面的零个或多个数字
     * @return
     */
    @RequestMapping("/category/{id:\\d*}")
    public String category(@PathVariable Long id) {
        Page page = getPage();

        IPage<PostVo> pageData = postService.paging(page, null, id, null, null, "created");
        req.setAttribute("pageData", pageData);
        req.setAttribute("currentCategoryId", id);

        return "post/category";
    }

    /**
     * 博客详情页面，点击现在博客详情和评论信息
     *
     * @param id
     * @return
     */
    @RequestMapping("/post/{id:\\d*}")
    public String view(@PathVariable Long id) {

        QueryWrapper wrapper = new QueryWrapper<Post>()
                .eq(id != null, "p.id", id);
        PostVo vo = postService.selectOne(wrapper);
        Assert.notNull(vo,"文章已经被删除");

        //同步文章阅读量
        postService.setViewCount(vo);

        IPage commentPage = commentService.paging(getPage(), null, id, "id");

        req.setAttribute("post", vo);
        req.setAttribute("pageData", commentPage);
        req.setAttribute("currentCategoryId", vo.getCategoryId());

        return "post/view";
    }

    /**
     *
     * 编辑文章，发布文章分为新发布和编辑编辑发布，我们可以根据前端是否传id来判断，如果有id，那么
     * 我们就通过id查询出来回显数据，所有新发布和编辑我们使用同一个方法，我们需要的数据有博客实体，
     * 还有分类列表，验证码三个。
     *
     */
//    @RequiresAuthentication
    @GetMapping("/post/edit")
    public String edit() {
        String id = req.getParameter("id");
        Post post = new Post();
        if(!StringUtils.isEmpty(id)) {
            post = postService.getById(Long.valueOf(id));
            Assert.notNull(post, "文章已被删除！");
            Long profileId = getProfileId();
            Assert.isTrue(post.getUserId()==getProfileId(), "无权限编辑此文章！");
        }

        List<Category> categories = categoryService.list(new QueryWrapper<Category>()
                .orderByDesc("order_num"));

        req.setAttribute("post", post);
        req.setAttribute("categories", categories);
        return "post/edit";
    }


    /**
     * 发布文章，发布文章要对文化在那个实体进行非空校验以及标题长度的校验
     *
     * 发布信息包括对文章实体的验证，人类验证(1+1=?)，这里不使用验证码验证了！！
     *
     * @param post
     * @param bindingResult
     * @param vercode
     * @return
     */
    @ResponseBody
    @Transactional
    @PostMapping("/post/submit")
    public Result submit(@Valid Post post, BindingResult bindingResult, String vercode) throws JsonProcessingException {

        if(!"2".equals(vercode)) {
            return Result.fail("人类认证错误！");
        }

        if(bindingResult.hasErrors()) {
            return Result.fail(bindingResult.getFieldError().getDefaultMessage());
        }

        if(post.getId() == null) {
            post.setUserId(getProfileId());

            post.setModified(new Date());
            post.setCreated(new Date());
            post.setCommentCount(0);
            post.setEditMode(null);
            post.setLevel(0);
            post.setRecommend(false);
            post.setViewCount(0);
            post.setVoteDown(0);
            post.setVoteUp(0);

        } else {
            Post tempPost = postService.getById(post.getId());
            Assert.isTrue(tempPost.getUserId()==getProfileId(), "无权限编辑此文章！");
        }

        postService.saveOrUpdate(post);

        return Result.succ("发布成功", null, "/post/" + post.getId());
    }

    /**
     * 删除文章
     * @param id
     * @return
     */
    @ResponseBody
    @Transactional
    @PostMapping("/post/delete")
    public Result delete(Long id) {
        Post post = postService.getById(id);

        Assert.notNull(post, "该帖子已被删除");
        Assert.isTrue(post.getUserId()==getProfileId(), "无权限删除此文章！");

        postService.removeById(id);

        // 删除相关消息、收藏等
        userMessageService.removeByMap(MapUtil.of("post_id", id));
        userCollectionService.removeByMap(MapUtil.of("post_id", id));

        return Result.succ("删除成功", null, "/center");
    }

}
